package top.gbyun.engine.actor;

import akka.actor.Props;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import top.gbyun.core.AbstractActorCreator;
import top.gbyun.core.ActorSystemContext;
import top.gbyun.core.entity.FlowInfo;
import top.gbyun.core.msg.NodeToFlowTellNextMsg;
import top.gbyun.engine.processor.FlowActorMsgProcessor;

/**
 * 流程Actor
 *
 * @author gengbin
 * @date 2024-12-19-14:58
 */
public class FlowActor extends ComponentActor<FlowActorMsgProcessor> {
    private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);

    public FlowActor(ActorSystemContext systemContext, FlowInfo flowInfo) {
        super(flowInfo.getId(), systemContext);
        setProcessor(new FlowActorMsgProcessor(flowInfo, systemContext));
    }

    /**
     * 创建actor的静态工厂方法
     *
     * @param flowInfo
     * @return akka.actor.Props
     * @author gengbin
     * @date 2024/12/19 15:56
     */
    public static Props props(ActorSystemContext systemContext, FlowInfo flowInfo) {
        return Props.create(FlowActor.class, () -> new FlowActor(systemContext, flowInfo));
    }


    /**
     * 消息接收器
     *
     * @return akka.actor.AbstractActor.Receive
     * @author gengbin
     * @date 2024/12/19 14:58
     */
    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .matchEquals("test", msg -> {
                    processor.test(getContext());
                })
                .match(NodeToFlowTellNextMsg.class, msg -> {
                    processor.onNodeToFlowTellNextMsg(getContext(), msg);
                })
                .matchAny(this::unhandled).build();
    }

    public static class ActorCreator extends AbstractActorCreator<FlowActor> {
        private static final long serialVersionUID = 1L;
        private final FlowInfo flowInfo;

        public ActorCreator(ActorSystemContext context, FlowInfo flowInfo) {
            super(context);
            this.flowInfo = flowInfo;
        }

        @Override
        public FlowActor create() throws Exception {
            return new FlowActor(context, flowInfo);
        }
    }
}
